package com.example.teacher.Service.Impl;

import com.alibaba.nacos.common.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.common.constants.MqConstants;
import com.example.common.constants.RdsConstants;
import com.example.common.constants.TakeConstants;
import com.example.common.domain.Messages.Mgs;
import com.example.common.domain.dto.WorkDto;
import com.example.common.domain.pojo.Course;
import com.example.common.domain.pojo.Homework;
import com.example.common.domain.pojo.Teacher;
import com.example.common.utils.CacheClient;
import com.example.teacher.Converter.HomeWorkConverter;
import com.example.teacher.Service.CourseService;
import com.example.teacher.Service.HomeworkService;
import com.example.teacher.Service.HomeworkStudentService;
import com.example.teacher.Service.TeacherService;
import com.example.teacher.mapper.HomeworkMapper;
import jakarta.persistence.EntityNotFoundException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class HomeworkServiceImpl extends ServiceImpl<HomeworkMapper, Homework> implements HomeworkService {
    @Autowired
    private CacheClient cacheClient;
    @Autowired
    private TeacherService teacherService;
    @Autowired
    private CourseService courseService;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private HomeworkMapper homeworkMapper;
    @Autowired
    private MessageConverter jsonMessageConverter; // 注入上面配置的转换器
    @Autowired
    private MessageConverter jsonMessageConverter2; // 注入上面配置的转换器
    @Autowired
    private HomeworkStudentService homeworkStudentService;

    @Override
    public Homework getHomeworkByIdWithLogicalExpire(String id) {
        // 使用逻辑过期策略获取教师信息
        return cacheClient.queryWithLogicalExpire(
                RdsConstants.HOMEWORK_INFO,
                id,
                Homework.class,
                this::getById, // 使用MyBatis-Plus的基础方法
                RdsConstants.CACHE_NULL_TTL,
                TimeUnit.MINUTES,
                false
        );
    }

    @Override        //发布作业
    public void sendAssignmentNotification(WorkDto workDto) {
        try {
            // 1. 从缓存获取教师信息
            Teacher teacher = teacherService.getTeacherByIdWithLogicalExpire(workDto.getTeacherId());
// 2. 从缓存获取课程信息
            Course course = courseService.getCourseByIdWithLogicalExpire(workDto.getCourseId());
            workDto.setTeacherId(teacher.getId());
            workDto.setCourseId(course.getId());
            // 4. 构建通知
            Mgs mgs = new Mgs(TakeConstants.HOMEWORK, workDto, LocalDateTime.now());
            mgs.setSender(teacher.getId());
            // 5. 发送到MQ
            rabbitTemplate.setMessageConverter(jsonMessageConverter);
            rabbitTemplate.convertAndSend(MqConstants.EXCHANGE_NOTIFICATION, "", mgs);  //保存到数据库并且messages服务，websocket发送
            log.info("作业通知发送成功: {}", workDto);
        } catch (Exception e) {
            log.error("作业通知发送失败", e);
            throw new RuntimeException("作业通知发送失败", e);
        }
    }

    @Override
    @Transactional
    public void saveHomework(WorkDto workDto) {
        Homework homework = HomeWorkConverter.WorkDtoTO(workDto);
        this.save(homework);
        homeworkStudentService.saveAllHomeworkStudent(homework);
    }

    @Override
    public void InsertHomework(Homework homework) {
        homeworkMapper.insert(homework);
    }

    public Page<Homework> queryHomeworkPage(WorkDto workDto, Integer pageNum, Integer pageSize) {
        // 1. 构建分页对象
        Page<Homework> page = new Page<>(pageNum, pageSize);
        // 2. 构建查询条件
        LambdaQueryWrapper<Homework> queryWrapper = new LambdaQueryWrapper<>();
        // 课程ID过滤
        if (StringUtils.hasText(workDto.getCourseId())) {
            queryWrapper.eq(Homework::getCourseId, workDto.getCourseId());
        }
        // 班级ID过滤
        if (StringUtils.hasText(workDto.getClassId())) {
            queryWrapper.eq(Homework::getClassId, workDto.getClassId());
        }
        // 教师ID过滤
        if (StringUtils.hasText(workDto.getTeacherId())) {
            queryWrapper.eq(Homework::getTeacherId, workDto.getTeacherId());
        }
        // 作业ID模糊查询
        if (StringUtils.hasText(workDto.getHomeworkId())) {
            queryWrapper.like(Homework::getId, workDto.getHomeworkId());
        }
        // 作业名称模糊查询
        if (StringUtils.hasText(workDto.getHomeworkName())) {
            queryWrapper.like(Homework::getHomeworkName, workDto.getHomeworkName());
        }
        // 开始时间范围过滤（大于等于起始时间）
        if (workDto.getStartTime() != null) {
            queryWrapper.ge(Homework::getStartTime, workDto.getStartTime());
        }
        // 结束时间范围过滤（小于等于更新时间）
        if (workDto.getUpdateTime() != null) {
            queryWrapper.le(Homework::getUpdateTime, workDto.getUpdateTime());
        }
        // 状态过滤（0:未结束，1:已结束）
        if (workDto.getStatus() != null) {
            queryWrapper.eq(Homework::getStatus, workDto.getStatus());
        }
        // 3. 执行分页查询（按更新时间倒序排列，最新作业在前）
        return homeworkMapper.selectPage(page, queryWrapper.orderByDesc(Homework::getUpdateTime));
    }

    @Override
    public void updateHomework(Homework homework) {
        // 参数校验：确保主键存在
        if (homework.getId() == null) {
            log.warn("更新作业时必须提供id");
            throw new IllegalArgumentException("更新作业时必须提供id");
        }
        // 构建UpdateWrapper
        UpdateWrapper<Homework> updateWrapper = new UpdateWrapper<>();
        // 设置更新条件（主键）
        updateWrapper.lambda()
                .eq(Homework::getId, homework.getId());

        // 动态设置需要更新的字段（只更新非null值）
        LambdaUpdateWrapper<Homework> lambdaUpdate = updateWrapper.lambda();
        // 基础字段更新
        if (homework.getCourseId() != null) {
            lambdaUpdate.set(Homework::getCourseId, homework.getCourseId());
        }
        if (homework.getClassId() != null) {
            lambdaUpdate.set(Homework::getClassId, homework.getClassId());
        }
        if (homework.getTeacherId() != null) {
            lambdaUpdate.set(Homework::getTeacherId, homework.getTeacherId());
        }
        if (homework.getHomeworkName() != null) {
            lambdaUpdate.set(Homework::getHomeworkName, homework.getHomeworkName());
        }
        // 时间字段更新
        if (homework.getStartTime() != null) {
            lambdaUpdate.set(Homework::getStartTime, homework.getStartTime());
        }
        if (homework.getUpdateTime() != null) { // 注意：实体类中字段名是updateTime，但实际应为endTime？
            lambdaUpdate.set(Homework::getUpdateTime, homework.getUpdateTime());
        }

        // 状态字段更新（附带业务逻辑）
        if (homework.getStatus() != null) {
            // 检查状态变更是否合法（例如：已结束的作业不能再变回未结束）
            if (homework.getStatus() == 1) { // 变更为"已结束"状态
                lambdaUpdate.set(Homework::getStatus, 1);
                // 可添加额外逻辑：自动设置结束时间为当前时间
                lambdaUpdate.set(Homework::getUpdateTime, new Timestamp(System.currentTimeMillis()));
            } else if (homework.getStatus() == 0) { // 变更为"未结束"状态
                lambdaUpdate.set(Homework::getStatus, 0);
            } else {
                log.warn("无效的作业状态值: {}", homework.getStatus());
                throw new IllegalArgumentException("作业状态值必须为0（未结束）或1（已结束）");
            }
        }
        // 自动更新时间戳（若实体类未通过注解自动处理）
        lambdaUpdate.set(Homework::getUpdateTime, new Timestamp(System.currentTimeMillis()));

        // 执行更新操作
        int rows = homeworkMapper.update(null, updateWrapper);
        // 检查更新结果
        if (rows == 0) {
            log.warn("更新作业失败，未找到记录，id={}", homework.getId());
            throw new EntityNotFoundException("未找到对应作业记录，id=" + homework.getId());
        }
    }


}
